...loading
2024-11-26
(2023년 10월에 작성된 회고록입니다)
이번 글에서는 담당 기능을 어떻게 구현했는지 작성해보려 합니다. 제가 담당한 부분은 메인 페이지의 검색기능입니다. 카테고리 및 몇몇 조건을 토대로 현재 가능한 숙소 목록을 렌더링해줍니다. 즉, 서버에서 숙소 목록을 잘 받아와 클라이언트들에게 잘 보여주는 역할을 잘 수행해야 했습니다. 데이터를 받아오는 것은 백엔드 팀이 잘해줘서 문제없었습니다. 문제는 제가 어떻게 클라이언트들에게 버그 없이 좋은 품질을 유지하며 데이터를 잘 보여줄 수 있는가에 있습니다..
메인 페이지 좀 구현은 복잡합니다.. 각 기능이 유기적으로 연결되어 있었지만, 좋은 설명을 위해 크게 세 부분으로 나누어 보겠습니다.
카테고리를 선택할 시, 해당 데이터를 예외 없이 잘 렌더링하는 것.
새로고침과 뒤로가기 등 브라우저의 기능을 고려하지 않고 코드를 작성함. 결과적으로, 새로고침이나 뒤로가기 시 카테고리에 맞지 않는 데이터가 렌더링 발생.
카테고리와 검색 필터를 전역 상태로 관리, 카테고리나 검색 필터 변경이 발생할 때 useEffect 훅을 사용하여 서버에 API 요청 전달.
카테고리 클릭 시, 해당 카테고리 값을 파라미터 ID로 갖는 경로로 이동하도록 구현했습니다. URL 경로가 바뀔 때마다 파라미터 ID 값으로 '검색 필터 State'를 갱신하여 API 요청을 보내줍니다. 즉, 검색 트리거에 '새로고침'과 '뒤로가기'의 브라우저 이벤트 또한 추가해준 셈이 됩니다. 따라서 새로고침이나 뒤로가기 이벤트가 발생하더라도 예외 없이 올바른 데이터를 서버로부터 응답받을 수 있었습니다.
: 리코일을 통해 숙박업소 검색 필터를 전역 상태로 저장합니다. 그리고 첫 페이지 진입 시, '호텔', '국내', '금일 기준 1박 2일', '2명' 을 기준으로 검색 API를 요청하여 상응하는 데이터를 불러옵니다. 해당 상태는 유저가 어플리케이션의 UI를 사용하거나, 새로고침 or 뒤로가기 이벤트를 발생시킬 때 업데이트 됩니다.
어플리케이션 UI를 사용할 때 트리거되는 로직은 간단합니다. 버튼 클릭 이벤트가 발생할 때 API 요청을 보내주면 됩니다. 문제는 브라우저의 새로고침 & 뒤로가기 이벤트를 어떻게 컨트롤할 것인가 입니다.
: 브라우저의 새로고침 & 뒤로가기 이벤트로 인한 검색 트리거는 URL 파라미터를 통해 컨트롤 할 수 있습니다. useNavigate & useParams 훅을 사용하여 로직을 구현합니다. 코드 내용은 다음과 같습니다. URL 경로가 바뀔 때마다 파라미터 값을 가져와 위 전역 상태의 카테고리 값을 갱신합니다. 이후 검색횟수(searchAttempt)에 변경을 주었습니다.
: 검색횟수(searchAttempt)에 변화가 생기면, 최신 필터 상태(전역 상태)값을 기준으로 API 요청을 보냈습니다. 성공적으로 클라이언트 동작에 상응하는 데이터를 가져올 수 있었으며, 새로고침 및 뒤로가기 이벤트에도 대응 가능해졌습니다.
참고로 검색횟수(searchingAttempt)를 추가로 설정한 이유는 Data fetching 코드를 관리하기 위해서 입니다. 유즈케이스를 고려해봤을 때 여러 곳에서 검색 트리거가 발생합니다. 발생하는 시점마다 Date Fetching 로직을 일일히 넣어주는 것은 개발자 경험을 저해합니다. 따라서 검색 트리거가 발생하는 순간 검색횟수(searchingAttempt)를 갱신했습니다. 그리고 검색횟수(searchingAttempt)가 갱신되는 것을 기준으로 Date fetching 코드를 관리했습니다.
검색 필터링 설정 후 '검색' 버튼 클릭 시, 해당 데이터를 예외 없이 렌더링
새로고침 시, 초기값으로 돌아가 클라이언트가 의도하지 않은 데이터가 렌더링
카테고리와 검색 필터를 전역 상태로 관리. 카테고리나 검색 필터 변경이 발생할 때 이를 감지하여 상응하는 API 요청
검색 필터링 또한 카테고리 구현에서 보여준 코드와 같습니다.
전역 상태로 검색 필터 목록을 관리했습니다. 새로고침 발생 시 전역 상태값이 디폴트값으로 돌아가지 않도록 하기 위해 recoil-persist
를 사용하여 값이 유지되도록 했습니다. 따라서 특정 페이지에서 새로고침이 발생해도 검색 필터가 초기화되지 않도록 했습니다.
더보기 버튼 클릭 시, 서버를 통해 16개의 숙박업소 데이터를 성공적으로 불러와 렌더링
현재 검색 카테고리와 응답 데이터의 불일치
페이지 인덱스를 증가시켜 전송하면, 서버에서는 해당 페이지 인덱스에 상응하는 숙박업소 데이터를 응답합니다. 하지만 카테고리가 변경될 때 페이지 인덱스를 0으로 초기화하지 않으면 이전 카테고리의 숙박업소 목록과 변경된 목록이 섞이는 문제가 발생했습니다.
(예: 호텔 데이터 page 0 + 한옥 데이터 page 1)
더보기 버튼 클릭 시, page 인덱스를 증가시켜 서버에 전송.
page 인덱스를 전역 상태로 지정하고, 카테고리 선택을 통해 페이지가 전환될 때마다 page 인덱스를 0으로 초기화하여 데이터가 섞이지 않도록 방지.
코드와 같이 카테고리 및 검색 필터링 변경이 발생하면 searchingAttempt(검색 시도)를 증가시켰습니다. 두 번째 useEffect의 의존성 배열을 확인해보면, searchingAttempt와 page가 담겨 있습니다. 해당 값이 변경되면 적절한 데이터 목록이 렌더링되도록 했습니다.
page 인덱스 상태값이 0일 경우, 첫 번째 페이지 데이터를 렌더링했습니다. 0이 아닐 경우, 더보기 버튼이 눌러져 page 인덱스가 증가되므로 추가적인 데이터 목록을 가져와 렌더링했습니다.
이상으로 구현한 메인 기능들을 정리했습니다. 메인 페이지라는 가장 중요한 부분을 맡았는데 막상 구현하고 나니 버그들을 마주하게 됐네요.. 시간이 지나고 다시 되돌아보니 처음부터 유저의 유즈케이스를 세심하게 구상하지 못하고 개발에 들어간게 부족했던 것 같습니다. 기능을 구현하니 '이 부분은 이렇게 되면 안되는데?'하는 부분들이 많았습니다. 개발을 시작하기 이전 충분히 고민해봤으면 처음부터 고려하고 투입될 부분이라 생각합니다. 급한 마음에 부랴부랴 추가적인 유즈케이스를 추가하다보니 코드 퀄리티도 다소 저하된 것 같네요.. 역시나 처음 시작이 중요한 것 같습니다. 급하더라도 처음부터 꼼꼼히 하는게 중요하다고 느끼는 경험입니다.
짧은 시간 동안 급하게 구현하느라 아직 리팩토링할 부분이 많이 남아 있습니다. 다음 포스팅에서는 메인 페이지의 성능 분석과 리펙토링 과정에 대해서 작성해보겠습니다.
Comments